home *** CD-ROM | disk | FTP | other *** search
- // Fmt - some simple single-arg sprintf-like routines
- //
- // It is apparently impossible to declare a Java method that accepts
- // variable numbers of any type of argument. You can declare it to take
- // Objects, but numeric variables and constants are not in fact Objects.
- //
- // However, using the built-in string concatenation, it's almost as
- // convenient to make a series of single-argument formatting routines.
- //
- // Fmt can format the following types:
- // int long float double char String Object
- // For each type there is a set of overloaded methods, each returning
- // a formatted String. There's the plain formatting version:
- // Fmt.fmt( x )
- // There's a version specifying a minimum field width:
- // Fmt.fmt( x, minWidth )
- // And there's a version that takes flags:
- // Fmt.fmt( x, minWidth, flags )
- // Currently available flags are:
- // Fmt.ZF - zero-fill
- // Fmt.LJ - left justify
- // Fmt.HX - hexadecimal
- // Fmt.OC - octal
- // For doubles and floats, there's a significant-figures parameter before
- // the flags:
- // Fmt.fmt( d )
- // Fmt.fmt( d, minWidth )
- // Fmt.fmt( d, minWidth, sigFigs )
- // Fmt.fmt( d, minWidth, sigFigs, flags )
- //
- // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions
- // are met:
- // 1. Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // 2. Redistributions in binary form must reproduce the above copyright
- // notice, this list of conditions and the following disclaimer in the
- // documentation and/or other materials provided with the distribution.
- //
- // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- // SUCH DAMAGE.
- //
- // Visit the ACME Labs Java page for up-to-date versions of this and other
- // fine Java utilities: http://www.acme.com/java/
-
- package PVS.Utils;
-
- public class Fmt
- {
-
- // Flags.
- public static final int ZF = 1; // zero-fill
- public static final int LJ = 2; // left justify
- public static final int HX = 4; // hexadecimal
- public static final int OC = 8; // octal
- private static final int WN = 16; // was a number - internal use
-
- // int
- public static String fmt( int i )
- {
- return fmt( i, 0, 0 );
- }
- public static String fmt( int i, int minWidth )
- {
- return fmt( i, minWidth, 0 );
- }
- public static String fmt( int i, int minWidth, int flags )
- {
- boolean hexadecimal = ( ( flags & HX ) != 0 );
- boolean octal = ( ( flags & OC ) != 0 );
- if ( hexadecimal )
- return fmt( Integer.toString( i, 16 ), minWidth, flags | WN );
- else if ( octal )
- return fmt( Integer.toString( i, 8 ), minWidth, flags | WN );
- else
- return fmt( Integer.toString( i ), minWidth, flags | WN );
- }
-
- // long
- public static String fmt( long l )
- {
- return fmt( l, 0, 0 );
- }
- public static String fmt( long l, int minWidth )
- {
- return fmt( l, minWidth, 0 );
- }
- public static String fmt( long l, int minWidth, int flags )
- {
- boolean hexadecimal = ( ( flags & HX ) != 0 );
- boolean octal = ( ( flags & OC ) != 0 );
- if ( hexadecimal )
- return fmt( Long.toString( l, 16 ), minWidth, flags | WN );
- else if ( octal )
- return fmt( Long.toString( l, 8 ), minWidth, flags | WN );
- else
- return fmt( Long.toString( l ), minWidth, flags | WN );
- }
-
- // float
- public static String fmt( float f )
- {
- return fmt( f, 0, 0, 0 );
- }
- public static String fmt( float f, int minWidth )
- {
- return fmt( f, minWidth, 0, 0 );
- }
- public static String fmt( float f, int minWidth, int sigFigs )
- {
- return fmt( f, minWidth, sigFigs, 0 );
- }
- public static String fmt( float f, int minWidth, int sigFigs, int flags )
- {
- if ( sigFigs != 0 )
- return fmt(
- sigFigFix( Float.toString( f ), sigFigs ), minWidth,
- flags | WN );
- else
- return fmt( Float.toString( f ), minWidth, flags | WN );
- }
-
- // double
- public static String fmt( double d )
- {
- return fmt( d, 0, 0, 0 );
- }
- public static String fmt( double d, int minWidth )
- {
- return fmt( d, minWidth, 0, 0 );
- }
- public static String fmt( double d, int minWidth, int sigFigs )
- {
- return fmt( d, minWidth, sigFigs, 0 );
- }
- public static String fmt( double d, int minWidth, int sigFigs, int flags )
- {
- if ( sigFigs != 0 )
- // Should really use something better than Double.toString() here.
- return fmt(
- sigFigFix( Double.toString( d ), sigFigs ), minWidth,
- flags | WN );
- else
- return fmt( Double.toString( d ), minWidth, flags | WN );
- }
-
- // char
- public static String fmt( char c )
- {
- return fmt( c, 0, 0 );
- }
- public static String fmt( char c, int minWidth )
- {
- return fmt( c, minWidth, 0 );
- }
- public static String fmt( char c, int minWidth, int flags )
- {
- // return fmt( Character.toString( c ), minWidth, flags );
- // Character currently lacks a static toString method. Workaround
- // is to make a temporary instance and use the instance toString.
- return fmt( new Character( c ).toString(), minWidth, flags );
- }
-
- // Object
- public static String fmt( Object o )
- {
- return fmt( o, 0, 0 );
- }
- public static String fmt( Object o, int minWidth )
- {
- return fmt( o, minWidth, 0 );
- }
- public static String fmt( Object o, int minWidth, int flags )
- {
- return fmt( o.toString(), minWidth, flags );
- }
-
- // String
- public static String fmt( String s )
- {
- return fmt( s, 0, 0 );
- }
- public static String fmt( String s, int minWidth )
- {
- return fmt( s, minWidth, 0 );
- }
- public static String fmt( String s, int minWidth, int flags )
- {
- int len = s.length();
- boolean zeroFill = ( ( flags & ZF ) != 0 );
- boolean leftJustify = ( ( flags & LJ ) != 0 );
- boolean hexadecimal = ( ( flags & HX ) != 0 );
- boolean octal = ( ( flags & OC ) != 0 );
- boolean wasNumber = ( ( flags & WN ) != 0 );
- if ( ( hexadecimal || octal || zeroFill ) && ! wasNumber )
- {
- System.err.println( "Acme.Fmt: number flag on a non-number" );
- return "***";
- }
- if ( zeroFill && leftJustify )
- {
- System.err.println( "Acme.Fmt: zero-fill left-justify is silly" );
- return "***";
- }
- if ( hexadecimal && octal )
- {
- System.err.println( "Acme.Fmt: can't do both hex and octal" );
- return "***";
- }
- if ( len >= minWidth )
- return s;
- int fillWidth = minWidth - len;
- StringBuffer fill = new StringBuffer( fillWidth );
- for ( int i = 0; i < fillWidth; ++i )
- if ( zeroFill )
- fill.append( '0' );
- else
- fill.append( ' ' );
- if ( leftJustify )
- return s + fill;
- else if ( zeroFill && s.startsWith( "-" ) )
- return "-" + fill + s.substring( 1 );
- else
- return fill + s;
- }
-
-
- private static String sigFigFix( String s, int sigFigs )
- {
- // First dissect the floating-point number string into sign,
- // integer part, fraction part, and exponent.
- String sign;
- String unsigned;
- if ( s.startsWith( "-" ) || s.startsWith( "+" ) )
- {
- sign = s.substring( 0, 1 );
- unsigned = s.substring( 1 );
- }
- else
- {
- sign = "";
- unsigned = s;
- }
- String mantissa;
- String exponent;
- int eInd = unsigned.indexOf( 'e' );
- if ( eInd == -1 )
- {
- mantissa = unsigned;
- exponent = "";
- }
- else
- {
- mantissa = unsigned.substring( 0, eInd );
- exponent = unsigned.substring( eInd );
- }
- StringBuffer number, fraction;
- int dotInd = mantissa.indexOf( '.' );
- if ( dotInd == -1 )
- {
- number = new StringBuffer( mantissa );
- fraction = new StringBuffer( "" );
- }
- else
- {
- number = new StringBuffer( mantissa.substring( 0, dotInd ) );
- fraction = new StringBuffer( mantissa.substring( dotInd + 1 ) );
- }
-
- int numFigs = number.length();
- int fracFigs = fraction.length();
- if ( ( numFigs == 0 || number.equals( "0" ) ) && fracFigs > 0 )
- {
- // Don't count leading zeros in the fraction.
- numFigs = 0;
- for ( int i = 0; i < fraction.length(); ++i )
- {
- if ( fraction.charAt( i ) != '0' )
- break;
- --fracFigs;
- }
- }
- int mantFigs = numFigs + fracFigs;
- if ( sigFigs > mantFigs )
- {
- // We want more figures; just append zeros to the fraction.
- for ( int i = mantFigs; i < sigFigs; ++i )
- fraction.append( '0' );
- }
- else if ( sigFigs < mantFigs && sigFigs >= numFigs )
- {
- // Want fewer figures in the fraction; chop.
- fraction.setLength(
- fraction.length() - ( fracFigs - ( sigFigs - numFigs ) ) );
- // Round?
- }
- else if ( sigFigs < numFigs )
- {
- // Want fewer figures in the number; turn them to zeros.
- fraction.setLength( 0 ); // should already be zero, but make sure
- for ( int i = sigFigs; i < numFigs; ++i )
- number.setCharAt( i, '0' );
- // Round?
- }
- // Else sigFigs == mantFigs, which is fine.
-
- if ( fraction.length() == 0 )
- return sign + number + exponent;
- else
- return sign + number + "." + fraction + exponent;
- }
-
-
- // Test program.
- public static void main( String[] args )
- {
- System.out.println( "Starting tests." );
- System.out.println( Fmt.fmt( "Hello there." ) );
- System.out.println( "#" + Fmt.fmt( 123 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123, 10 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123, 10, Fmt.ZF ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123, 10, Fmt.LJ ) + "#" );
- System.out.println( "#" + Fmt.fmt( -123 ) + "#" );
- System.out.println( "#" + Fmt.fmt( -123, 10 ) + "#" );
- System.out.println( "#" + Fmt.fmt( -123, 10, Fmt.ZF ) + "#" );
- System.out.println( "#" + Fmt.fmt( -123, 10, Fmt.LJ ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123, 0, Fmt.HX ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123, 0, Fmt.OC ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123456000000000000.0 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456, 0, 8 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456, 0, 7 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456, 0, 6 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456, 0, 5 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456, 0, 4 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456, 0, 3 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456, 0, 2 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123.456, 0, 1 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 123456000000000000.0, 0, 4 ) + "#" );
- System.out.println( "#" + Fmt.fmt( -123.456, 0, 4 ) + "#" );
- System.out.println( "#" + Fmt.fmt( -123456000000000000.0, 0, 4 ) + "#" );
- System.out.println( "#" + Fmt.fmt( 'c' ) + "#" );
- System.out.println( "#" + Fmt.fmt( new java.util.Date() ) + "#" );
- System.out.println( "Done with tests." );
- }
- }
-